<template>
    <div class="page_root" :key="queryUpdateFlag" data-page-name="项目模板维护" data-page-identification="b_m730qrjod4">
        <a-spin :spinning="pageLoading.loading" :tip="pageLoading.tip">
            <!-- begin vid_tmbu89crd9 自定义模板_eqthivse55 -->
            <a-row :slots="'4:20'">
                <a-col :span="4" class="left-article">
                    <a-row>
                        <al-box justify="between" align="center">
                            <div style="font-size: 16px; font-weight: bold; color: #262626">目录列表</div>
                            <div class="right-btn">
                                <div>
                                    <!--                                <a-button type="link" class="role-btn" size="small" @click="handleChangeRole">-->
                                    <!--                                    <template #icon>-->
                                    <!--                                        <span class="role-btn-pic"></span>-->
                                    <!--                                    </template>-->
                                    <!--                                    角色管理-->
                                    <!--                                </a-button>-->
                                    <div class="role-comm-icon" @click="handleChangeRole" title="角色管理"> </div>
                                </div>
                                <!--                            <span-->
                                <!--                                @click="handleTemplateManagerOpen"-->
                                <!--                                style="-->
                                <!--                                    cursor: pointer;-->
                                <!--                                    color: rgba(56, 117, 255, 1);-->
                                <!--                                    border-style: none;-->
                                <!--                                    display: inline-block;-->
                                <!--                                    height: 24px;-->
                                <!--                                    line-height: 24px;-->
                                <!--                                "-->
                                <!--                                ><PlusOutlined />新建</span-->
                                <!--                            >-->
                                <div class="add-icon" @click="handleTemplateManagerOpen" title="新建"></div>
                            </div>
                        </al-box>
                    </a-row>
                    <al-box class="search">
                        <a-input
                            autocomplete="off"
                            v-model:value="state.templateName"
                            placeholder="请输入"
                            :allowClear="true"
                            @change="getTemplateList"
                        >
                            <template #suffix>
                                <search-outlined />
                            </template>
                        </a-input>
                    </al-box>
                    <al-box class="tree" style="height: 800px; overflow: auto">
                        <a-tree
                            v-model:checkedKeys="state.treeProps.checkedKeys"
                            v-model:selectedKeys="state.treeProps.selectedKeys"
                            v-model:expandedKeys="state.treeProps.expandedKeys"
                            :fieldNames="{ children: 'children', title: 'templateName', key: 'templateId' }"
                            :selectedBackgroundColor="'#EBF1FF'"
                            :backgroundColor="'#F5F5F5'"
                            :tree-data="state.templateList"
                            @select="handleTreeSelect"
                        >
                            <template #title="{ templateName, templateId }" class="btn-show">
                                <div class="tree-btns">
                                    <span>{{ (templateId, templateName) }}</span>
                                    <div
                                        v-if="templateId.includes('下线')"
                                        style="display: inline-block"
                                        @click.stop="handleOnline(getStatusPrefix(templateId))"
                                    >
                                        <a-tooltip>
                                            <template #title>发布模板</template>
                                            <svg
                                                style="margin-left: 8px"
                                                class="svg-icon"
                                                xmlns="http://www.w3.org/2000/svg"
                                                xmlns:xlink="http://www.w3.org/1999/xlink"
                                                width="16px"
                                                height="16px"
                                                viewBox="0 0 16 16"
                                                version="1.1"
                                            >
                                                <title>发布</title>
                                                <g
                                                    id="平台图标整理-22.12.21"
                                                    stroke="none"
                                                    stroke-width="1"
                                                    fill="none"
                                                    fill-rule="evenodd"
                                                >
                                                    <g id="发布">
                                                        <rect
                                                            id="矩形"
                                                            fill="#FFFFFF"
                                                            opacity="0"
                                                            x="0"
                                                            y="0"
                                                            width="16"
                                                            height="16"
                                                        />
                                                        <g
                                                            id="编组-127"
                                                            transform="translate(2, 2)"
                                                            stroke="#3875FF"
                                                            stroke-linecap="round"
                                                        >
                                                            <path
                                                                d="M3.05586851,3.8409282 C2.09134059,4.387584 1.12681268,4.93423981 0.162284762,5.48089561 C0.114236686,5.50812734 0.0973617004,5.56915368 0.124593426,5.61720175 C0.134304365,5.63433588 0.148858559,5.64822103 0.166430387,5.6571155 L11.8276095,11.5597466 C11.876885,11.5846888 11.9370503,11.5649627 11.9619924,11.5156873 C11.9713337,11.4972327 11.9747226,11.4763356 11.9716923,11.4558747 L10.2953971,0.137634715 C10.2873057,0.0830021793 10.2364579,0.0452731236 10.1818254,0.0533645101 C10.171104,0.0549524039 10.1607121,0.0582726834 10.1510563,0.0631954306 L6.42866151,1.9609467 L6.42866151,1.9609467"
                                                                id="路径-126"
                                                                transform="translate(6, 5.8235) scale(1, -1) translate(-6, -5.8235)"
                                                            />
                                                            <path
                                                                d="M11.7315455,0.45535249 C11.7315455,0.45535249 4.38576092,8.76777557 4.38576092,8.76777557 C4.38576092,8.76777557 4.38576092,9.85253405 4.38576092,12.022051"
                                                                id="路径-127"
                                                            />
                                                        </g>
                                                    </g>
                                                </g>
                                            </svg>
                                        </a-tooltip>
                                    </div>
                                    <div
                                        v-if="templateId.includes('上线')"
                                        style="display: inline-block"
                                        @click.stop="handleOffline(getStatusPrefix(templateId))"
                                    >
                                        <a-tooltip>
                                            <template #title>下线模板</template>
                                            <span style="margin-left: 8px; color: #595959">
                                                <svg
                                                    class="svg-icon"
                                                    xmlns="http://www.w3.org/2000/svg"
                                                    xmlns:xlink="http://www.w3.org/1999/xlink"
                                                    width="16px"
                                                    height="16px"
                                                    viewBox="0 0 16 16"
                                                    version="1.1"
                                                >
                                                    <title>下线</title>
                                                    <g
                                                        id="平台图标整理-22.12.21"
                                                        stroke="none"
                                                        stroke-width="1"
                                                        fill="none"
                                                        fill-rule="evenodd"
                                                    >
                                                        <g id="下线">
                                                            <rect
                                                                id="矩形"
                                                                fill="#FFFFFF"
                                                                opacity="0"
                                                                x="0"
                                                                y="0"
                                                                width="16"
                                                                height="16"
                                                            />
                                                            <path
                                                                d="M13.544,2 C13.305413,2 13.112,2.18081029 13.112,2.40380299 C13.112,5.04564699 10.8205934,7.1872847 7.994,7.1872847 C5.16740665,7.1872847 2.876,5.04564699 2.876,2.40380299 C2.87271813,2.17990619 2.67757682,2 2.438,2 C2.32239045,1.99853811 2.21096184,2.04041391 2.12864378,2.11629763 C2.04632571,2.19218135 2,2.29573938 2,2.40380299 C2.00417146,4.27930076 3.0112079,6.02869111 4.68344165,7.06538894 C6.3556754,8.10208676 8.47170193,8.28883279 10.322,7.56300953 C12.546084,6.69057133 13.9949815,4.65817298 14,2.40380299 C13.9967181,2.17990619 13.8015768,2 13.562,2 L13.544,2 Z"
                                                                id="路径"
                                                                fill="#3875FF"
                                                                fill-rule="nonzero"
                                                                transform="translate(8, 5) scale(1, -1) translate(-8, -5)"
                                                            />
                                                            <path
                                                                d="M5.41136558,8.50068595 C5.52246,8.50451992 5.62979976,8.45914187 5.70605388,8.37610602 L7.57819127,6.45401567 L7.57819127,13.5728688 C7.58135182,13.8097233 7.76927947,14 8,14 C8.22976732,14 8.41603053,13.8087669 8.41603053,13.5728688 L8.41603053,6.45401567 L10.2881679,8.37610602 C10.3674294,8.45820381 10.4760714,8.50324916 10.5886344,8.50068595 C10.6994611,8.50302439 10.806233,8.45788641 10.8833227,8.37610602 C11.0388924,8.21061196 11.0388924,7.94836232 10.8833227,7.78286826 L8.30046649,5.11329833 C8.13596071,4.96223389 7.8871521,4.96223389 7.72264631,5.11329833 L5.11667729,7.7710035 C4.96110757,7.93649756 4.96110757,8.19874721 5.11667729,8.36424126 C5.193767,8.44602166 5.30053889,8.49115964 5.41136558,8.48882119 L5.41136558,8.50068595 Z"
                                                                id="路径"
                                                                fill="#3875FF"
                                                                fill-rule="nonzero"
                                                                transform="translate(8, 9.5) scale(1, -1) translate(-8, -9.5)"
                                                            />
                                                        </g>
                                                    </g>
                                                </svg>
                                            </span>
                                        </a-tooltip>
                                    </div>
                                    <div
                                        style="display: inline-block; margin: 0 5px"
                                        @click.stop="handleEditTemplate(getStatusPrefix(templateId))"
                                    >
                                        <a-tooltip>
                                            <template #title>编辑</template>
                                            <svg
                                                class="svg-icon"
                                                xmlns="http://www.w3.org/2000/svg"
                                                xmlns:xlink="http://www.w3.org/1999/xlink"
                                                width="16px"
                                                height="16px"
                                                viewBox="0 0 16 16"
                                                version="1.1"
                                            >
                                                <title>编辑</title>
                                                <g
                                                    id="平台图标整理-22.12.21"
                                                    stroke="none"
                                                    stroke-width="1"
                                                    fill="none"
                                                    fill-rule="evenodd"
                                                >
                                                    <g id="图标/通用图标/编辑">
                                                        <rect
                                                            id="矩形备份-164"
                                                            fill="#D8D8D8"
                                                            opacity="0"
                                                            x="0"
                                                            y="0"
                                                            width="16"
                                                            height="16"
                                                        />
                                                        <g
                                                            id="编组-97"
                                                            transform="translate(2.7292, 2.1119)"
                                                            stroke="#3875FF"
                                                        >
                                                            <polygon
                                                                id="路径-51"
                                                                stroke-linejoin="round"
                                                                points="0.392089844 7.39355469 7.90966797 0 10.4321289 2.43847656 2.76501465 10.1097412 -7.23874357e-17 10.3608398"
                                                            />
                                                            <line
                                                                x1="0.677001953"
                                                                y1="6.99987793"
                                                                x2="3.25"
                                                                y2="9.61315918"
                                                                id="路径-52"
                                                            />
                                                            <line
                                                                x1="6.25390625"
                                                                y1="1.36975098"
                                                                x2="8.8269043"
                                                                y2="3.98303223"
                                                                id="路径-52备份"
                                                            />
                                                            <line
                                                                x1="4.18286133"
                                                                y1="11.4564209"
                                                                x2="10.8640137"
                                                                y2="11.4564209"
                                                                id="路径-53"
                                                                stroke-linecap="round"
                                                            />
                                                        </g>
                                                    </g>
                                                </g>
                                            </svg>
                                        </a-tooltip>
                                    </div>
                                    <a-popconfirm @confirm="handleDeleteTemplate(templateId)" title="确定删除吗？">
                                        <div none style="display: inline-block">
                                            <a-tooltip>
                                                <template #title>删除</template>
                                                <svg
                                                    class="svg-icon"
                                                    xmlns="http://www.w3.org/2000/svg"
                                                    xmlns:xlink="http://www.w3.org/1999/xlink"
                                                    width="16px"
                                                    height="16px"
                                                    viewBox="0 0 16 16"
                                                    version="1.1"
                                                >
                                                    <title>删除</title>
                                                    <g
                                                        id="平台图标整理-22.12.21"
                                                        stroke="none"
                                                        stroke-width="1"
                                                        fill="none"
                                                        fill-rule="evenodd"
                                                    >
                                                        <g id="图标/通用图标/废纸篓">
                                                            <rect
                                                                id="矩形备份-141"
                                                                fill="#D8D8D8"
                                                                opacity="0"
                                                                x="0"
                                                                y="0"
                                                                width="16"
                                                                height="16"
                                                            />
                                                            <g
                                                                id="编组-41"
                                                                transform="translate(2.447, 1.9153)"
                                                                stroke="#3875FF"
                                                            >
                                                                <path
                                                                    d="M3.13500977,0 L8.13500977,0 C8.41115214,-1.06237683e-16 8.63500977,0.223857625 8.63500977,0.5 L8.63500977,2.37451172 L8.63500977,2.37451172 L2.63500977,2.37451172 L2.63500977,0.5 C2.63500977,0.223857625 2.85886739,-2.16934637e-17 3.13500977,0 Z"
                                                                    id="矩形"
                                                                />
                                                                <line
                                                                    x1="0"
                                                                    y1="2.37451172"
                                                                    x2="11.0124512"
                                                                    y2="2.37451172"
                                                                    id="路径-17"
                                                                    stroke-linecap="round"
                                                                />
                                                                <path
                                                                    d="M1.12670898,2.37451172 L1.6077387,12.109515 C1.62089354,12.3757405 1.84057902,12.5848389 2.10712942,12.5848389 L9.065223,12.5848389 C9.33492782,12.5848389 9.55602897,12.3709336 9.56494943,12.1013763 L9.88684082,2.37451172 L9.88684082,2.37451172 L1.12670898,2.37451172 Z"
                                                                    id="路径-18"
                                                                />
                                                                <line
                                                                    x1="4.00842285"
                                                                    y1="5.90539551"
                                                                    x2="4.00842285"
                                                                    y2="8.625"
                                                                    id="路径-19"
                                                                    stroke-linecap="round"
                                                                />
                                                                <line
                                                                    x1="6.97338867"
                                                                    y1="5.90539551"
                                                                    x2="6.97338867"
                                                                    y2="8.625"
                                                                    id="路径-19备份"
                                                                    stroke-linecap="round"
                                                                />
                                                            </g>
                                                        </g>
                                                    </g>
                                                </svg>
                                            </a-tooltip>
                                        </div>
                                    </a-popconfirm>
                                </div>
                            </template>
                        </a-tree>
                    </al-box>
                </a-col>
                <a-col :span="20" class="right-article">
                    <al-box justify="between" style="margin-bottom: 16px" align="center">
                        <div class="text">题目详情</div>
                        <div class="right-tj">
                            <div v-if="state.templateType === '交付项目'">
                                任务类型：
                                <a-radio-group v-model:value="state.taskType" @change="radioChange">
                                    <a-radio value="主流程">主流程</a-radio>
                                    <a-radio value="数据专项">数据专项</a-radio>
                                    <a-radio value="全品种专项">全品种专项</a-radio>
                                </a-radio-group>
                            </div>
                            <div style="display: flex; gap: 16px; align-items: center">
                                <div class="approve-type"
                                    >模板类型：<span style="font-weight: 600; color: #3875ff">
                                        {{ state.templateType }}</span
                                    >
                                </div>
                                <div class="approve-status"
                                    >审批状态：<span style="font-weight: 600; color: #3875ff">
                                        {{ state.approveStatus }}</span
                                    >
                                </div>
                                <a-button type="primary" @click="handleOpenStageModal">项目阶段维护</a-button>
                                <a-button type="primary" @click="handleAddTask">新建任务</a-button>
                            </div>
                        </div>
                    </al-box>
                    <al-box class="table-wrapper" v-if="state.templateType === '交付项目'">
                        <a-table
                            class="vid_a7g6eyj5wh"
                            :bordered="true"
                            :data-source="state.templateDetailList"
                            :columns="state.tableProps.columns"
                            :pagination="false"
                            :scroll="{ x: scrollX, y: state.templateDetailList.length ? '637px' : '' }"
                            @resizeColumn="handleTaskResizeColumn"
                            :loading="state.tableLoading"
                        >
                            <template #bodyCell="{ column, record, text }">
                                <template v-if="column.dataIndex === 'stageName'">
                                    {{ record.stageSerialNumber + '.' + record.stageName }}
                                </template>
                                <template v-if="column.dataIndex === 'dependencyTemplateTaskName'">
                                    {{ record.dependencyTemplateTaskSerialNumber }}
                                    {{ record.dependencyTemplateTaskName }}
                                </template>
                                <template v-if="state.tableProps.formatColumnsList.includes(column.dataIndex)">
                                    <a-tooltip placement="top" :overlayStyle="{ maxWidth: 'unset' }" color="#fff">
                                        <template #title>
                                            <p
                                                style="color: #262626; margin: 0"
                                                v-for="(item, index) in formatStringBySemi(text)"
                                                :key="index"
                                            >
                                                {{ item }}</p
                                            >
                                        </template>
                                        <div class="table-text">{{ text }}</div>
                                    </a-tooltip>
                                </template>

                                <template v-if="column.dataIndex === 'attachmentList'">
                                    <div
                                        class="ellipsis download-text"
                                        type="link"
                                        v-for="(item, index) in record.attachmentList"
                                        :key="index"
                                        @click="downloadFile(item)"
                                        :title="item.name"
                                        >{{ item.name }}
                                    </div>
                                </template>

                                <template v-if="column.dataIndex === 'operate'">
                                    <a-button
                                        style="padding: 0"
                                        size="small"
                                        type="link"
                                        @click="handleEditTask(record)"
                                    >
                                        编辑</a-button
                                    >
                                    <a-divider style="margin: 0 10px; border-color: #3875ff" type="vertical" />
                                    <a-popconfirm
                                        title="是否确认删除该任务？确认后对应任务的所有数据全部删除"
                                        @confirm="handleDeleteTask(record.templateTaskId)"
                                    >
                                        <a-button type="link">删除</a-button>
                                    </a-popconfirm>
                                </template>
                            </template>
                        </a-table>
                    </al-box>
                    <al-box class="table-wrapper" v-else>
                        <a-table
                            class="vid_a7g6eyj5wh"
                            :bordered="true"
                            :data-source="state.templateDetailList"
                            :columns="state.tableProps.ptColumns"
                            :pagination="false"
                            :scroll="{ x: scrollX, y: state.templateDetailList.length ? '637px' : '' }"
                            @resizeColumn="handleTaskResizeColumn"
                        >
                            <template #bodyCell="{ column, record, text }">
                                <template v-if="column.dataIndex === 'stageName'">
                                    {{ record.stageSerialNumber + '.' + record.stageName }}
                                </template>
                                <template v-if="column.dataIndex === 'dependencyTemplateTaskName'">
                                    {{ record.dependencyTemplateTaskSerialNumber }}
                                    {{ record.dependencyTemplateTaskName }}
                                </template>
                                <template v-if="state.tableProps.formatColumnsList.includes(column.dataIndex)">
                                    <a-tooltip placement="top" :overlayStyle="{ maxWidth: 'unset' }" color="#fff">
                                        <template #title>
                                            <p
                                                style="color: #262626; margin: 0"
                                                v-for="(item, index) in formatStringBySemi(text)"
                                                :key="index"
                                            >
                                                {{ item }}</p
                                            >
                                        </template>
                                        <div class="table-text">{{ text }}</div>
                                    </a-tooltip>
                                </template>

                                <template v-if="column.dataIndex === 'attachmentList'">
                                    <div
                                        class="ellipsis download-text"
                                        type="link"
                                        v-for="(item, index) in record.attachmentList"
                                        :key="index"
                                        @click="downloadFile(item)"
                                        :title="item.name"
                                        >{{ item.name }}
                                    </div>
                                </template>

                                <template v-if="column.dataIndex === 'operate'">
                                    <a-button
                                        style="padding: 0"
                                        size="small"
                                        type="link"
                                        @click="handleEditTask(record)"
                                    >
                                        编辑</a-button
                                    >
                                    <a-divider style="margin: 0 10px; border-color: #3875ff" type="vertical" />
                                    <a-popconfirm
                                        title="是否确认删除该任务？确认后对应任务的所有数据全部删除"
                                        @confirm="handleDeleteTask(record.templateTaskId)"
                                    >
                                        <a-button type="link">删除</a-button>
                                    </a-popconfirm>
                                </template>
                            </template>
                        </a-table>
                    </al-box>
                </a-col>
            </a-row>
            <!-- 管理模板 -->
            <a-modal
                v-model:visible="state.templateManagerVisible"
                :title="state.title"
                :width="860"
                :maskClosable="false"
                :centered="true"
                :destroy-on-close="true"
                @ok="handleTemplateManagerOk"
            >
                <a-form
                    ref="templateRef1"
                    name="dynamic_form_item"
                    :model="state.modalTemplateList"
                    :rules="state.templateRules"
                >
                    <a-row>
                        <a-col :span="24">
                            <a-form-item
                                label="模板类型"
                                :label-col="{ span: 4 }"
                                :wrapper-col="{ span: 20 }"
                                name="templateType"
                                :rules="state.templateRules.templateType"
                            >
                                <a-select
                                    :options="[
                                        {
                                            label: '平台项目',
                                            value: '平台项目'
                                        },
                                        {
                                            label: '交付项目',
                                            value: '交付项目'
                                        }
                                    ]"
                                    :disabled="state.isEdit"
                                    v-model:value="state.modalTemplateList.templateType"
                                    placeholder="请输入"
                                    :maxlength="12"
                                />
                            </a-form-item>
                        </a-col>
                        <a-col :span="24">
                            <a-form-item
                                label="模板名称"
                                :label-col="{ span: 4 }"
                                :wrapper-col="{ span: 20 }"
                                name="templateName"
                                :rules="state.templateRules.templateName"
                            >
                                <a-input
                                    :disabled="state.isEdit && state.isDisabled"
                                    v-model:value="state.modalTemplateList.templateName"
                                    placeholder="请输入"
                                    :maxlength="12"
                                />
                            </a-form-item>
                        </a-col>
                        <a-col :span="24">
                            <a-form-item
                                label="模板编码"
                                :label-col="{ span: 4 }"
                                :wrapper-col="{ span: 20 }"
                                name="templateCode"
                                :rules="state.templateRules.templateCode"
                            >
                                <a-input
                                    :disabled="state.isEdit"
                                    v-model:value="state.modalTemplateList.templateCode"
                                    placeholder="请输入"
                                    :maxlength="20"
                                />
                            </a-form-item>
                        </a-col>
                        <a-form-item name="templateId">
                            <a-input
                                v-model:value="state.modalTemplateList.templateId"
                                :maxlength="20"
                                disabled
                                type="hidden"
                            />
                        </a-form-item>
                    </a-row>
                    <a-row v-if="state.isEdit">
                        <a-col :span="24"
                            ><span style="color: #aaaaaa; margin-left: 20px">模板内容需要先下线再编辑</span></a-col
                        >
                    </a-row>
                </a-form>
            </a-modal>
            <!-- 项目阶段维护 -->
            <a-modal
                v-model:visible="state.projectStageVisible"
                :width="850"
                :maskClosable="false"
                :centered="true"
                :body-style="{ maxHeight: '700px', overflow: 'auto' }"
                @ok="handleStageManagerOk"
                :ok-button-props="{ loading: state.milepostLoading }"
            >
                <template #title>
                    <span v-if="state.templateType === '交付项目'"> 项目阶段维护--{{ state.taskType }}</span>
                    <span v-else> 项目阶段维护</span>
                </template>
                <a-form ref="templateRef2" :model="state" :rules="state.stageRules">
                    <a-row :gutter="24" v-for="(item, index) in state.templateStageList" :key="item.uid">
                        <a-col :span="11">
                            <a-form-item
                                label="项目阶段名称"
                                :label-col="{ span: 7 }"
                                :wrapper-col="{ span: 17 }"
                                :name="['templateStageList', index, 'stageName']"
                                :rules="state.stageRules.stageName"
                            >
                                <a-input v-model:value="item.stageName" placeholder="请输入" :maxlength="20" />
                            </a-form-item>
                        </a-col>
                        <a-col :span="11">
                            <a-form-item
                                label="项目阶段序号"
                                :label-col="{ span: 7 }"
                                :wrapper-col="{ span: 17 }"
                                :name="['templateStageList', index, 'serialNumber']"
                                :rules="state.stageRules.serialNumber"
                            >
                                <a-input
                                    v-model:value="item.serialNumber"
                                    placeholder="请输入"
                                    :maxlength="4"
                                    :disabled="!!item.templateStageId"
                                />
                            </a-form-item>
                        </a-col>
                        <a-col :span="1">
                            <a-button
                                style="margin-left: 0"
                                type="link"
                                class="template-delete"
                                @click="handleDeleteStage(index, item)"
                                size="small"
                                >删除
                            </a-button>
                        </a-col>
                        <a-form-item :name="['templateStageList', index, 'templateStageId']">
                            <a-input v-model:value="item.templateStageId" :maxlength="20" disabled type="hidden" />
                        </a-form-item>
                    </a-row>
                </a-form>

                <a-button type="primary" ghost class="addRowBtn" @click="handleAddStage">
                    <template #icon>
                        <plus-outlined />
                    </template>
                    新增
                </a-button>
            </a-modal>
            <!-- 新建任务 -->
            <a-modal
                v-model:visible="state.taskVisible"
                :title="state.modalTaskTitle"
                :width="900"
                :maskClosable="false"
                :centered="true"
                okText="保存"
                class="task-modal"
                :destroy-on-close="true"
                :body-style="state.bodyStyle"
                @ok="handleTaskOk"
            >
                <a-form :model="state.taskForm" ref="templateRef3" class="task-form" :rules="state.taskRules">
                    <div class="title">基础信息</div>
                    <div v-if="state.templateType === '交付项目'">
                        <a-row>
                            <a-col :span="24">
                                <a-form-item
                                    label="任务类型"
                                    name="taskType"
                                    :label-col="{ span: 3 }"
                                    :wrapper-col="{ span: 21 }"
                                >
                                    <a-select
                                        :options="[
                                            {
                                                label: '主流程',
                                                value: '主流程'
                                            },
                                            {
                                                label: '数据专项',
                                                value: '数据专项'
                                            },
                                            {
                                                label: '全品种专项',
                                                value: '全品种专项'
                                            }
                                        ]"
                                        v-model:value="state.taskForm.taskType"
                                        @change="jfMbChange"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row>
                            <a-col :span="12">
                                <a-form-item
                                    label="所属项目阶段"
                                    :label-col="{ span: 6 }"
                                    :wrapper-col="{ span: 18 }"
                                    name="templateStageId"
                                >
                                    <a-select v-model:value="state.taskForm.templateStageId" placeholder="请选择">
                                        <a-select-option
                                            v-for="item in state.templateStageList"
                                            :value="item.templateStageId"
                                        >
                                            {{ item.stageName }}
                                        </a-select-option>
                                    </a-select>
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="依赖任务"
                                    :label-col="{ span: 6 }"
                                    :wrapper-col="{ span: 18 }"
                                    name="dependencyTemplateTaskId"
                                >
                                    <a-tree-select
                                        v-model:value="state.taskForm.dependencyTemplateTaskId"
                                        show-search
                                        style="width: 100%"
                                        :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
                                        allow-clear
                                        treeDefaultExpandAll
                                        :tree-data="ylTaskData"
                                        @focus="getYlTask(getStatusPrefix(state.treeProps.selectedKeys[0]))"
                                        tree-node-filter-prop="taskName"
                                        :field-names="{
                                            children: 'children',
                                            label: 'taskName',
                                            value: 'taskId'
                                        }"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row>
                            <a-col :span="24">
                                <a-form-item
                                    label="任务名称"
                                    :label-col="{ span: 3 }"
                                    :wrapper-col="{ span: 21 }"
                                    name="taskName"
                                >
                                    <a-input
                                        v-model:value="state.taskForm.taskName"
                                        :maxlength="20"
                                        placeholder="请输入"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row>
                            <a-col :span="12">
                                <a-form-item
                                    label="任务序号"
                                    :label-col="{ span: 6 }"
                                    :wrapper-col="{ span: 18 }"
                                    name="serialNumber"
                                >
                                    <a-input
                                        v-model:value="state.taskForm.serialNumber"
                                        :maxlength="6"
                                        placeholder="请输入"
                                        :disabled="state.taskForm.templateTaskId"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="人天"
                                    :label-col="{ span: 6 }"
                                    :wrapper-col="{ span: 18 }"
                                    name="workingHours"
                                >
                                    <a-input
                                        v-model:value="state.taskForm.workingHours"
                                        :maxlength="8"
                                        placeholder="请输入"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row style="margin: 1px 0 5px">
                            <a-col :span="12">
                                <a-form-item
                                    label="标记"
                                    :label-col="{ span: 6 }"
                                    :wrapper-col="{ span: 18 }"
                                    name="mark"
                                >
                                    <a-radio-group v-model:value="state.taskForm.mark">
                                        <a-radio value="">无</a-radio>
                                        <a-radio value="里程碑">里程碑</a-radio>
                                        <a-radio value="初验">初验</a-radio>
                                        <a-radio value="终验">终验</a-radio>
                                    </a-radio-group>
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="组任务" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
                                    <a-checkbox v-model:checked="state.taskForm.groupTask" />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row style="margin: 0px 0 -4px">
                            <a-col :span="12">
                                <a-form-item
                                    label="任务周期分类"
                                    :label-col="{ span: 6 }"
                                    :wrapper-col="{ span: 18 }"
                                    name="periodClassify"
                                >
                                    <a-radio-group
                                        v-model:value="state.taskForm.periodClassify"
                                        :disabled="state.radioDisabled"
                                    >
                                        <a-radio value="T" style="margin-right: 16px">T</a-radio>
                                        <a-radio value="N">N</a-radio>
                                    </a-radio-group>
                                </a-form-item>
                            </a-col>
                            <span class="tips" style="margin-left: -183px; padding-top: 24px; line-height: 1">
                                <exclamation-circle-outlined />
                                N为项目开始的时间，T为启动会开始时间，例：N+3、T+5
                            </span>
                        </a-row>
                        <a-row>
                            <a-col :span="12">
                                <a-form-item
                                    label="开始时间"
                                    :label-col="{ span: 6 }"
                                    :wrapper-col="{ span: 18 }"
                                    name="periodClassifyStart"
                                    style="display: flex; justify-content: center"
                                >
                                    <span style="display: inline-block; margin-right: 11px; width: 23px"
                                        >{{ state.taskForm.periodClassify }}+</span
                                    >
                                    <a-input
                                        style="width: 89%"
                                        v-model:value="state.taskForm.periodClassifyStart"
                                        :maxlength="10000"
                                        placeholder="请输入"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="结束时间"
                                    :label-col="{ span: 6 }"
                                    :wrapper-col="{ span: 18 }"
                                    name="periodClassifyEnd"
                                >
                                    <span style="display: inline-block; margin-right: 11px; width: 23px"
                                        >{{ state.taskForm.periodClassify }}+</span
                                    >
                                    <a-input
                                        style="width: 89%"
                                        v-model:value="state.taskForm.periodClassifyEnd"
                                        :maxlength="20"
                                        placeholder="请输入"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row>
                            <a-col :span="12">
                                <a-form-item
                                    label="任务负责人"
                                    :label-col="{ span: 6 }"
                                    :wrapper-col="{ span: 18 }"
                                    name="directorRole"
                                >
                                    <a-select
                                        v-model:value="state.taskForm.directorRole"
                                        placeholder="请选择"
                                        @focus="getRolePeople"
                                        :options="directorRoleList"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="审核员"
                                    :label-col="{ span: 6 }"
                                    :wrapper-col="{ span: 18 }"
                                    name="auditorRole"
                                >
                                    <a-select
                                        v-model:value="state.taskForm.auditorRole"
                                        placeholder="请选择"
                                        :options="directorRoleList"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-divider style="margin-top: 5px" />
                        <div class="title"
                            ><span style="font-size: 14px; color: #ff4d4f; margin-right: 4px">*</span>完成标准</div
                        >
                        <a-row>
                            <a-col :span="24">
                                <a-form-item :wrapper-col="{ span: 24 }" name="finishStandard">
                                    <a-textarea
                                        :rows="3"
                                        v-model:value="state.taskForm.finishStandard"
                                        placeholder="请输入"
                                    />
                                </a-form-item>
                                <div class="tips" style="margin-top: -4px">
                                    请用”；“号区分不同细项的内容，格式参考：<br />
                                    1）设计反讲机制及频率、并执行；<br />
                                    2）通过反讲，确认研发、产品、测试和现场项目人员等各角色均已对产品设计形成统一认知；
                                </div>
                            </a-col>
                        </a-row>
                    </div>
                    <div v-else class="pt-template">
                        <a-row>
                            <a-col :span="24">
                                <a-form-item label="所属项目阶段" name="templateStageId">
                                    <a-select v-model:value="state.taskForm.templateStageId" placeholder="请选择">
                                        <a-select-option
                                            v-for="item in state.templateStageList"
                                            :value="item.templateStageId"
                                        >
                                            {{ item.stageName }}
                                        </a-select-option>
                                    </a-select>
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row>
                            <a-col :span="12">
                                <a-form-item label="任务名称" name="taskName">
                                    <a-input
                                        v-model:value="state.taskForm.taskName"
                                        :maxlength="20"
                                        placeholder="请输入"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="任务序号" name="serialNumber">
                                    <a-input
                                        v-model:value="state.taskForm.serialNumber"
                                        :maxlength="6"
                                        placeholder="请输入"
                                        :disabled="state.taskForm.templateTaskId"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row style="margin: 1px 0 5px">
                            <a-col :span="12">
                                <a-form-item label="任务负责人" name="directorRole">
                                    <a-select
                                        v-model:value="state.taskForm.directorRole"
                                        placeholder="请选择"
                                        @focus="getRolePeople"
                                        :options="directorRoleList"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                    </div>
                    <a-divider style="margin-top: 5px" />
                    <div class="title">审核标准</div>
                    <a-row>
                        <a-col :span="24">
                            <a-form-item :wrapper-col="{ span: 24 }" name="assessorStandard">
                                <a-textarea
                                    :rows="3"
                                    v-model:value="state.taskForm.assessorStandard"
                                    placeholder="请输入"
                                />
                            </a-form-item>
                            <div class="tips">
                                请用”；“号区分不同细项的内容，格式参考：<br />
                                1）设计反讲机制及频率、并执行；<br />
                                2）通过反讲，确认研发、产品、测试和现场项目人员等各角色均已对产品设计形成统一认知；
                            </div>
                        </a-col>
                    </a-row>
                    <a-divider />
                    <div v-if="state.templateType === '交付项目'">
                        <div class="title">注意事项</div>
                        <a-row>
                            <a-col :span="24">
                                <a-form-item :wrapper-col="{ span: 24 }" name="note">
                                    <a-textarea :rows="3" v-model:value="state.taskForm.note" placeholder="请输入" />
                                </a-form-item>
                                <div class="tips">
                                    请用”；“号区分不同细项的内容，格式参考：<br />
                                    1）设计反讲机制及频率、并执行；<br />
                                    2）通过反讲，确认研发、产品、测试和现场项目人员等各角色均已对产品设计形成统一认知；
                                </div>
                            </a-col>
                        </a-row>
                        <a-divider style="border-color: #d9d9d9" />
                    </div>
                    <div v-if="state.templateType === '交付项目'">
                        <div class="title">SOP</div>
                        <a-row>
                            <a-col :span="24">
                                <a-form-item :wrapper-col="{ span: 24 }" name="note">
                                    <a-textarea :rows="3" v-model:value="state.taskForm.sop" placeholder="请输入" />
                                </a-form-item>
                                <div class="tips">
                                    请用”；“号区分不同细项的内容，格式参考：<br />
                                    1）设计反讲机制及频率、并执行；<br />
                                    2）通过反讲，确认研发、产品、测试和现场项目人员等各角色均已对产品设计形成统一认知；
                                </div>
                            </a-col>
                        </a-row>
                        <a-divider style="border-color: #d9d9d9" />
                    </div>
                    <div v-if="state.templateType === '平台项目'">
                        <div class="title">执行SOP</div>
                        <a-row>
                            <a-col :span="24">
                                <a-form-item :wrapper-col="{ span: 24 }" name="note">
                                    <a-textarea :rows="3" v-model:value="state.taskForm.sop" placeholder="请输入" />
                                </a-form-item>
                                <div class="tips">
                                    请用”；“号区分不同细项的内容，格式参考：<br />
                                    1）设计反讲机制及频率、并执行；<br />
                                    2）通过反讲，确认研发、产品、测试和现场项目人员等各角色均已对产品设计形成统一认知；
                                </div>
                            </a-col>
                        </a-row>
                        <a-divider style="border-color: #d9d9d9" />
                    </div>
                    <div v-if="state.templateType === '交付项目'">
                        <div class="title">甲方工作事项</div>
                        <a-row>
                            <a-col :span="24">
                                <a-form-item :wrapper-col="{ span: 24 }" name="workItem">
                                    <a-textarea
                                        :rows="3"
                                        v-model:value="state.taskForm.workItem"
                                        placeholder="请输入"
                                    />
                                </a-form-item>
                                <div class="tips">
                                    请用”；“号区分不同细项的内容，格式参考：<br />
                                    1）设计反讲机制及频率、并执行；<br />
                                    2）通过反讲，确认研发、产品、测试和现场项目人员等各角色均已对产品设计形成统一认知；
                                </div>
                            </a-col>
                        </a-row>
                        <a-divider />
                    </div>

                    <div class="title">模板附件</div>
                    <a-row>
                        <a-col :span="24">
                            <a-form-item :wrapper-col="{ span: 24 }" name="attachmentList">
                                <a-upload
                                    v-model:file-list="state.taskForm.attachmentList"
                                    :multiple="true"
                                    :before-upload="handlerUpload"
                                    @remove="handlerRemove"
                                    accept=".xlsx, image/*,.docx,, .xls,.mp4"
                                >
                                    <a-button type="primary">
                                        <upload-outlined />
                                        上传
                                    </a-button>
                                </a-upload>
                            </a-form-item>
                        </a-col>
                    </a-row>
                    <a-row v-if="state.templateType === '交付项目'">
                        <a-col :span="24">
                            <a-form-item
                                label="备注"
                                :label-col="{ span: 24 }"
                                :wrapper-col="{ span: 24 }"
                                name="description"
                            >
                                <a-textarea v-model:value="state.taskForm.description" placeholder="请输入" />
                            </a-form-item>
                        </a-col>
                    </a-row>
                </a-form>
            </a-modal>
            <!-- 新建任务 -->
            <!--      角色管理-->
            <a-modal
                v-model:visible="state.roleVisible"
                title="角色管理"
                :width="770"
                :maskClosable="false"
                :centered="true"
                @ok="handleSubmitRole"
                :body-style="bodyStyle"
            >
                <a-form ref="leaderRef" :model="state">
                    <div class="role-father"><div class="role-title">项目领导小组</div></div>
                    <!--                    <div class="role-div">-->
                    <a-row :gutter="24" v-for="(item, index) in state.leaderModel" :key="item.uid">
                        <a-col :span="11">
                            <a-form-item
                                label="角色名称"
                                :label-col="{ span: 7 }"
                                :wrapper-col="{ span: 17 }"
                                :name="['leaderModel', index, 'roleName']"
                                :rules="[{ required: true, validator: validateLeaderName, trigger: 'blur' }]"
                            >
                                <a-input v-model:value="item.roleName" placeholder="请输入" :maxlength="20" />
                            </a-form-item>
                        </a-col>
                        <a-col :span="11">
                            <a-form-item
                                label="排序"
                                :label-col="{ span: 7 }"
                                :wrapper-col="{ span: 17 }"
                                :name="['leaderModel', index, 'serialNumber']"
                                :rules="[{ required: true, validator: validateLeader, trigger: 'blur' }]"
                            >
                                <a-input-number
                                    min="0"
                                    style="width: 100%"
                                    v-model:value="item.serialNumber"
                                    placeholder="请输入"
                                    :maxlength="4"
                                />
                            </a-form-item>
                        </a-col>
                        <a-col :span="1">
                            <a-button
                                style="margin-left: 0"
                                type="link"
                                class="template-delete"
                                @click="deleteLeader(index, item)"
                                size="small"
                                >删除
                            </a-button>
                        </a-col>
                    </a-row>
                    <!--                    </div>-->
                </a-form>

                <a-button type="primary" ghost class="addRowBtn" @click="handleAddLeader">
                    <template #icon>
                        <plus-outlined />
                    </template>
                    新增
                </a-button>

                <a-form ref="responsibleRef" :model="state">
                    <div class="role-father"><div class="role-title">项目负责人</div></div>
                    <!--                    <div class="role-div">-->
                    <a-row :gutter="24" v-for="(item, index) in state.responsibleModel" :key="item.uid">
                        <a-col :span="11">
                            <a-form-item
                                label="角色名称"
                                :label-col="{ span: 7 }"
                                :wrapper-col="{ span: 17 }"
                                :name="['responsibleModel', index, 'roleName']"
                                :rules="[{ required: true, validator: validateResponsibleName, trigger: 'blur' }]"
                            >
                                <a-input v-model:value="item.roleName" placeholder="请输入" :maxlength="20" />
                            </a-form-item>
                        </a-col>
                        <a-col :span="11">
                            <a-form-item
                                label="排序"
                                :label-col="{ span: 7 }"
                                :wrapper-col="{ span: 17 }"
                                :name="['responsibleModel', index, 'serialNumber']"
                                :rules="[{ required: true, validator: validateResponsible, trigger: 'blur' }]"
                            >
                                <a-input-number
                                    style="width: 100%"
                                    min="0"
                                    v-model:value="item.serialNumber"
                                    placeholder="请输入"
                                    :maxlength="4"
                                />
                            </a-form-item>
                        </a-col>
                        <a-col :span="1">
                            <a-button
                                style="margin-left: 0"
                                type="link"
                                class="template-delete"
                                @click="deleteResponsible(index, item)"
                                size="small"
                                >删除
                            </a-button>
                        </a-col>
                    </a-row>
                    <!--                    </div>-->
                </a-form>

                <a-button type="primary" ghost class="addRowBtn-role" @click="handleAddResponsible">
                    <template #icon>
                        <plus-outlined />
                    </template>
                    新增
                </a-button>

                <a-form ref="memberRef" :model="state">
                    <div class="role-father"><div class="role-title">项目组核心成员</div></div>
                    <!--                    <div class="role-div">-->
                    <a-row :gutter="24" v-for="(item, index) in state.memberModel" :key="item.uid">
                        <a-col :span="11">
                            <a-form-item
                                label="角色名称"
                                :label-col="{ span: 7 }"
                                :wrapper-col="{ span: 17 }"
                                :name="['memberModel', index, 'roleName']"
                                :rules="[{ required: true, validator: validateSerialName, trigger: 'blur' }]"
                            >
                                <a-input v-model:value="item.roleName" placeholder="请输入" :maxlength="20" />
                            </a-form-item>
                        </a-col>
                        <a-col :span="11">
                            <a-form-item
                                label="排序"
                                :label-col="{ span: 7 }"
                                :wrapper-col="{ span: 17 }"
                                :name="['memberModel', index, 'serialNumber']"
                                :rules="[{ required: true, validator: validateSerial, trigger: 'blur' }]"
                            >
                                <a-input-number
                                    style="width: 100%"
                                    v-model:value="item.serialNumber"
                                    placeholder="请输入"
                                    min="0"
                                    :maxlength="4"
                                />
                            </a-form-item>
                        </a-col>
                        <a-col :span="1">
                            <a-button
                                style="margin-left: 0"
                                type="link"
                                class="template-delete"
                                @click="deleteMember(index, item)"
                                size="small"
                                >删除
                            </a-button>
                        </a-col>
                    </a-row>
                    <!--                    </div>-->
                </a-form>

                <a-button type="primary" ghost class="addRowBtn-role-last" @click="handleAddMember">
                    <template #icon>
                        <plus-outlined />
                    </template>
                    新增
                </a-button>
            </a-modal>
            <!--      角色管理-->
            <!-- end vid_tmbu89crd9 自定义模板_eqthivse55 -->
        </a-spin>
    </div>
</template>
<script setup lang="tsx">
    import {
        h,
        ref,
        reactive,
        toRaw,
        markRaw,
        watch,
        computed,
        onBeforeMount,
        onMounted,
        onBeforeUnmount,
        onUnmounted,
        onActivated,
        onDeactivated
    } from 'vue'
    import { useRoute, useRouter } from 'vue-router'
    const router = useRouter()
    const route = useRoute()
    import { get, post, put, del, request, requestWithHeaders } from '@/utils/http/Axios'
    import {
        cloneDeep,
        localGet,
        merge,
        getDifferenceArray,
        traversalTreeStructure,
        checkCaseCondition,
        renderStringInTemplate,
        handleBreadcrumbJump,
        throttle,
        permission,
        getComponentParamsValue
    } from '@/utils/index'
    import { isNullOrEmpty, isEmptyArr, isNullOrUnDef, isContained, isArray, isEmpty, isObject } from '@/utils/is'
    import dayjs from 'dayjs'
    import { getPagePcChartsDataSourceConvert } from '@/utils/chart'
    import { message, notification, Modal } from 'ant-design-vue'
    import {
        propertyFormatByNumber,
        propertyFormatByPercentage,
        propertyFormatByDate,
        parseSubFromDataList
    } from '@/utils/format'
    import colorTheme from '@/design/custom-theme.json'
    /*** PUBLISH_EXEGESIS ***
 import UserTableRecords from '@/model/UserTableRecords';
 import { getAppBaseUrl } from '@/utils/index';
 import { sendToken } from "@/hooks/useIframeToken";
 import { useSystemStore } from "@/store/modules/system";
 const systemStore = useSystemStore();
 *** PUBLISH_EXEGESIS ***/

    // 获取传入的流程ID和组件参数
    const props = defineProps({
        'processInstanceId': {
            type: [String, Number, Boolean],
            default: undefined
        }
    })
    const immediateWatch = (source, callback) => {
        watch(source, callback, { deep: true, immediate: true })
    }

    /* -------------------------- 属性定义 -------------------------- */

    const setTimeOutList = []
    const pageLoading = reactive({
        loading: false,
        tip: undefined
    })
    const authInfo = localGet('app-user-store')

    // 处理校验
    const setSubFormName = (parentInfo, name) => {
        return [parentInfo.parents, parentInfo.cycleIndex, name]
    }

    /* ========================== 属性定义 ========================== */

    /* -------------------------- 元素数据引用 -------------------------- */

    /* ========================== 元素数据引用 ========================== */

    /* -------------------------- 页面数据 -------------------------- */

    /* ========================== 页面数据 ========================== */

    /* -------------------------- 响应 -------------------------- */

    /* ========================== 响应 ========================== */

    /* -------------------------- 函数 -------------------------- */

    /* ========================== 函数 ========================== */

    /* -------------------------- 页面参数 -------------------------- */

    const pageParameter_state = reactive({
        'processInstanceId': props.processInstanceId ?? route.query.processInstanceId
    })

    /* ========================== 页面参数 ========================== */

    /* -------------------------- 组件事件处理方法 -------------------------- */

    // ---------------------------- 组件数据同步 ----------------------------

    // ============================ 组件数据同步 ============================

    /* ========================== 组件事件处理方法 ========================== */

    /* -------------------------- 生命周期 -------------------------- */
    // 用于参数变更后重新执行自定义指令
    const queryUpdateFlag = ref(0)
    onMounted(() => {})

    onUnmounted(() => {
        // 销毁定时器
        setTimeOutList.forEach(({ repeat, timer }) => {
            repeat ? clearInterval(timer) : clearTimeout(timer)
        })
    })

    /* ========================== 生命周期 ========================== */

    /* -------------------------- 数据关联处理 -------------------------- */

    /* -------------------------- 表单数据同步 -------------------------- */
    /* ========================== 表单数据同步 ========================== */

    /* ========================== 数据关联处理 ========================== */

    /* -------------------------- 不同组件自定义的处理逻辑 -------------------------- */

    /* ========================== 不同组件自定义的处理逻辑 ========================== */

    // ================================定制化逻辑========================================
    const bodyStyle = {
        paddingBottom: '0',
        paddingTop: '16px',
        height: '700px',
        overflow: 'auto'
    }
    const validateTemplateCode = (rule, value, name) => {
        if (value) {
            const reg = new RegExp(/^[1-9]\d*$/)
            if (!reg.test(value)) {
                return Promise.reject('请输入正整数')
            } else {
                return Promise.resolve()
            }
        } else {
            return Promise.reject('请输入模板编码')
        }
    }

    const validateStageCode = (rule, value) => {
        if (value !== undefined && value !== null) {
            const reg = new RegExp(/^(0|([1-9][0-9]*))(\.\d{1,2})?$/)
            if (!reg.test(value)) {
                return Promise.reject('请输入小数点后两位以内的正数数字')
            } else {
                return Promise.resolve()
            }
        } else {
            return Promise.reject('请输入项目阶段序号')
        }
    }

    const workingHoursValidate = async (rule, value, callback) => {
        if (!value) {
            return Promise.reject('请输入人天')
        }
        if (!/^[1-9]\d*\.5$|0\.5$|^[1-9]\d*$/.test(value)) {
            return Promise.reject(new Error('请输入0.5为倍数的正数数字'))
        }
    }

    const timeValidate = async (rule, value, callback) => {
        if (!value) {
            return Promise.reject('请输入')
        }
        if (!/^[0-9]{1,4}$/.test(value)) {
            return Promise.reject(new Error('请输入0-10000以内的整数数字'))
        }
    }

    const initTaskForm = () => ({
        templateStageId: undefined, //项目阶段id
        taskType: undefined, //项目类型
        templateTaskId: undefined, //任务id
        taskName: undefined, //任务名称
        serialNumber: undefined, //任务序号
        workingHours: undefined, //预计投入工时/人天
        mark: '', //标记
        groupTask: false, //标记
        periodClassify: 'T', //周期分类
        periodClassifyStart: undefined, //周期分类开始时间
        periodClassifyEnd: undefined, //周期分类结束时间
        directorRole: undefined, //负责人角色
        auditorRole: undefined, //审核员角色
        finishStandard: undefined, //完成标准
        assessorStandard: undefined, //审核标准
        workItem: undefined, //甲方工作事项
        note: undefined, //注意事项
        attachmentList: [], //附件
        description: undefined, //备注
        sop: undefined, //sop,
        dependencyTemplateTaskId: undefined //依赖任务
    })

    const auditorRoleList = [
        { value: '项目总监', label: '项目总监' },
        { value: 'PMO', label: 'PMO' },
        { value: '副总裁', label: '副总裁' },
        { value: '数据实施总监', label: '数据实施总监' },
        { value: '项目经理', label: '项目经理' },
        { value: '产品经理', label: '产品经理' },
        { value: '技术经理', label: '技术经理' }
    ]

    const state = reactive({
        templateType: '',
        approveStatus: '',
        title: '',
        templateManagerVisible: false,
        projectStageVisible: false,
        isEdit: false,
        isDisabled: false,
        tableLoading: false,
        milepostLoading: false,
        taskType: '主流程',
        bodyStyle: {
            height: '700px',
            overflow: 'auto',
            padding: '24px 24px 0px 24px'
        },
        taskVisible: false,
        ptTaskVisible: false,
        templateName: '',
        treeProps: {
            lazyParams: undefined,
            selected: { singleValue: '', title: [], value: [], option: [], singleLabel: '' },
            clickNode: { nodeTitle: '', nodeKey: '', nodeParentKey: '' },
            checkedKeys: [],
            selectedKeys: [],
            expandedKeys: [],
            treeData: []
        },
        tableProps: {
            columns: [
                {
                    title: '项目阶段',
                    dataIndex: 'stageName',
                    ellipsis: true,
                    align: 'left',
                    width: '140px',
                    fixed: 'left',
                    customCell: item => {
                        const { rowIndex, rowSpan } = item
                        return {
                            rowSpan: rowSpan,
                            style: {
                                fontSize: '16px',
                                color: '#262626',
                                fontWeight: '600',
                                borderTop: rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '任务序号',
                    dataIndex: 'serialNumber',
                    ellipsis: true,
                    align: 'center',
                    width: '100px',
                    fixed: 'left',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '任务名称',
                    dataIndex: 'taskName',
                    ellipsis: true,
                    align: 'center',
                    resizable: true,
                    fixed: 'left',
                    width: '100px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },

                {
                    title: '任务负责人（角色）',
                    dataIndex: 'directorRole',
                    ellipsis: true,
                    align: 'center',
                    width: '180px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '审核员（角色）',
                    dataIndex: 'auditorRole',
                    ellipsis: true,
                    align: 'center',
                    width: '160px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '开始时间',
                    dataIndex: 'periodClassifyStart',
                    ellipsis: true,
                    align: 'center',
                    width: '100px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '结束时间',
                    dataIndex: 'periodClassifyEnd',
                    ellipsis: true,
                    align: 'center',
                    width: '100px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '人天',
                    dataIndex: 'workingHours',
                    ellipsis: true,
                    align: 'center',
                    width: '80px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '依赖任务',
                    dataIndex: 'dependencyTemplateTaskName',
                    ellipsis: true,
                    align: 'center',
                    width: '180px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '模板附件',
                    dataIndex: 'attachmentList',
                    ellipsis: true,
                    align: 'center',
                    width: '140px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '完成标准',
                    dataIndex: 'finishStandard',
                    ellipsis: true,
                    align: 'center',
                    width: '100px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '审核标准',
                    dataIndex: 'assessorStandard',
                    ellipsis: true,
                    align: 'center',
                    width: '100px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '注意事项',
                    dataIndex: 'note',
                    ellipsis: true,
                    align: 'center',
                    width: '100px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: 'SOP',
                    dataIndex: 'sop',
                    ellipsis: true,
                    align: 'center',
                    width: '100px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '甲方工作事项',
                    dataIndex: 'workItem',
                    ellipsis: true,
                    align: 'center',
                    width: '150px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '标记',
                    dataIndex: 'mark',
                    ellipsis: true,
                    align: 'center',
                    width: '80px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '关键路径',
                    dataIndex: 'mark',
                    ellipsis: true,
                    align: 'center',
                    width: '120px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '备注',
                    dataIndex: 'description',
                    ellipsis: true,
                    align: 'center',
                    width: '80px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '操作',
                    dataIndex: 'operate',
                    align: 'center',
                    fixed: 'right',
                    width: '150px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                }
            ],
            ptColumns: [
                {
                    title: '项目阶段',
                    dataIndex: 'stageName',
                    ellipsis: true,
                    align: 'left',
                    width: '140px',
                    fixed: 'left',
                    customCell: item => {
                        const { rowIndex, rowSpan } = item
                        return {
                            rowSpan: rowSpan,
                            style: {
                                fontSize: '16px',
                                color: '#262626',
                                fontWeight: '600',
                                borderTop: rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '任务序号',
                    dataIndex: 'serialNumber',
                    ellipsis: true,
                    align: 'center',
                    width: '100px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '任务名称',
                    dataIndex: 'taskName',
                    ellipsis: true,
                    align: 'center',
                    resizable: true,
                    width: '100px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },

                {
                    title: '负责人',
                    dataIndex: 'directorRole',
                    ellipsis: true,
                    align: 'center',
                    width: '150px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '审核标准',
                    dataIndex: 'assessorStandard',
                    ellipsis: true,
                    align: 'center',
                    width: '100px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '模板附件',
                    dataIndex: 'attachmentList',
                    ellipsis: true,
                    align: 'center',
                    width: '140px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '执行SOP',
                    dataIndex: 'sop',
                    ellipsis: true,
                    align: 'center',
                    width: '100px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                },
                {
                    title: '操作',
                    dataIndex: 'operate',
                    align: 'center',
                    fixed: 'right',
                    width: '150px',
                    customCell: ({ rowSpan, rowIndex, border }) => {
                        return {
                            style: {
                                borderTop: border && rowIndex ? '1px solid #3875ff' : 'none'
                            }
                        }
                    }
                }
            ],
            formatColumnsList: ['finishStandard', 'assessorStandard', 'note', 'workItem', 'sop']
        },
        templateList: [],
        // 模板下阶段
        templateStageList: [],
        // 包含项目阶段和任务详情
        templateDetailList: [],
        // 当前模板
        currentTemplateInfo: null,
        currentStageId: null,
        currentTemplateTaskList: [],
        templateRules: {
            templateName: [{ required: true, message: '请输入模板名称', trigger: 'blur' }],
            templateCode: [{ required: true, validator: validateTemplateCode, trigger: 'blur' }],
            templateType: [{ required: true, message: '请选择模板类型', trigger: 'blur' }]
        },
        stageRules: {
            stageName: [{ required: true, message: '请输入项目阶段名称', trigger: 'blur' }],
            serialNumber: [{ required: true, validator: validateStageCode, trigger: 'blur' }]
        },
        taskRules: {
            templateStageId: [{ required: true, message: '请选择所属项目阶段', trigger: 'blur' }],
            taskType: [{ required: true, message: '请选择任务类型', trigger: 'blur' }],
            taskName: [{ required: true, message: '请输入任务名称', trigger: 'blur' }],
            serialNumber: [{ required: true, message: '请输入任务序号', trigger: 'blur' }],
            workingHours: [{ required: true, validator: workingHoursValidate, trigger: 'blur' }],
            mark: [{ message: '请选择标记', trigger: 'blur' }],
            periodClassify: [{ required: true, message: '请选择周期分类', trigger: 'blur' }],
            periodClassifyStart: [{ required: true, validator: timeValidate, trigger: 'blur' }],
            periodClassifyEnd: [{ required: true, validator: timeValidate, trigger: 'blur' }],
            directorRole: [{ required: true, message: '请选择任务负责人', trigger: 'blur' }],
            auditorRole: [{ required: true, message: '请选择审核员', trigger: 'blur' }],
            finishStandard: [{ required: true, message: '请输入完成标准', trigger: 'blur' }]
        },
        modalTemplateList: {},
        modalStageList: [],
        templateStatusLoadingId: undefined,
        modalTaskTitle: '新建任务',
        editTaskId: null,
        taskForm: initTaskForm(),
        uploadProps: {
            uploadFile: data =>
                request({
                    url: '/file-storage/api/v1/file/upload',
                    method: 'POST',
                    responseType: 'blob',
                    withCredentials: false,
                    data,
                    timeout: 360000,
                    headers: {}
                })
        },
        radioDisabled: false,
        roleVisible: false,
        leaderModel: [],
        responsibleModel: [],
        memberModel: []
    })

    const templateRef1 = ref()
    const templateRef2 = ref()
    const templateRef3 = ref()

    watch(
        () => state.templateList,
        list => {
            if (!list.length) {
                return
            }
            state.treeProps.selectedKeys = [list[0].templateId]
            state.templateType = list[0].templateType
            getTaskList(getStatusPrefix(list[0].templateId))
            getTemplateDetail(getStatusPrefix(list[0].templateId))
        },
        { deep: true, immediate: true }
    )

    const handleTemplateManagerOpen = () => {
        state.title = '新建模板'
        state.isEdit = false
        state.modalTemplateList = {
            templateId: null,
            templateName: undefined,
            templateCode: undefined,
            templateType: undefined,
            status: '下线',
            uid: $guid()
        }

        state.templateManagerVisible = true
    }
    function handleEditTemplate(templateId) {
        get(`/solution-ppm/api/v2/built-in-system-ppm/project/template/detail/${templateId}`).then(data => {
            if (data.code === 200) {
                if (data.data.approvalStatus?.includes('审批中') && data.data.approvalStatus) {
                    message.info('请通过审批再进行此操作')
                } else {
                    if (data.data.status === '上线') {
                        state.isDisabled = true
                    } else {
                        state.isDisabled = false
                    }
                    state.modalTemplateList.templateName = data.data.templateName
                    state.modalTemplateList.templateCode = data.data.templateCode
                    state.modalTemplateList.templateId = data.data.templateId
                    state.modalTemplateList.templateType = data.data.templateType
                    state.title = '编辑模板'
                    state.isEdit = true
                    state.templateManagerVisible = true
                }
            } else {
                message.error(data.message)
            }
        })
    }
    function handleTaskResizeColumn(w, col) {
        col.width = w
    }
    function radioChange() {
        getTaskList(getStatusPrefix(state.treeProps.selectedKeys[0]))
    }
    const scrollX = state.tableProps.columns.reduce((pre, cur) => {
        return parseInt(pre.width) + parseInt(cur.width)
    }, {})

    const handleTreeSelect = (selectKeys, e) => {
        state.templateType = e.node.templateType
        if (state.templateType === '交付项目') {
            state.taskType = '主流程'
        } else {
            state.taskType = ''
        }
        console.log(e)
        getTaskList(getStatusPrefix(selectKeys[0]))
        getTemplateDetail(getStatusPrefix(selectKeys[0]))
    }
    function getTemplateDetail(templateId) {
        get(`/solution-ppm/api/v2/built-in-system-ppm/project/template/detail/${templateId}`).then(data => {
            state.approveStatus = data.data.approvalStatus
        })
    }
    const handleTemplateManagerOk = () => {
        templateRef1.value.validateFields().then(res => {
            if (state.isEdit === false) {
                //   新建
                post('/solution-ppm/api/v2/built-in-system-ppm/project/template/create', state.modalTemplateList).then(
                    data => {
                        if (data.code === 200) {
                            message.success('操作成功')
                            state.templateManagerVisible = false
                            getTemplateList()
                        } else {
                            message.error(data.message)
                        }
                    }
                )
            } else {
                // 编辑
                put(`/solution-ppm/api/v2/built-in-system-ppm/project/template/modify`, state.modalTemplateList).then(
                    data => {
                        if (data.code === 200) {
                            message.success('操作成功')
                            state.templateManagerVisible = false
                            getTemplateList()
                        } else {
                            message.info(data.message)
                        }
                    }
                )
            }
        })
    }

    const handleStageManagerOk = () => {
        templateRef2.value.validateFields().then(res => {
            state.milepostLoading = true
            updateStageList(getStatusPrefix(state.treeProps.selectedKeys[0]), res.templateStageList, () => {
                getTaskList(getStatusPrefix(state.treeProps.selectedKeys[0]), () => {
                    state.projectStageVisible = false
                    message.success('保存成功')
                })
            })
        })
    }

    const handleTaskOk = () => {
        templateRef3.value.validateFields().then(res => {
            if (Number(res.periodClassifyStart) > Number(res.periodClassifyEnd)) {
                message.error('开始时间不能小于结束时间')
                return
            }
            if (!state.taskForm.templateTaskId) {
                handleCreateTask()
            } else {
                handleUpdateTask()
            }
        })
    }

    const handleAddStage = () => {
        state.templateStageList.push({
            stageName: undefined,
            serialNumber: undefined,
            uid: $guid()
        })
    }

    // 打开项目阶段维护
    const handleOpenStageModal = () => {
        if (!state.treeProps.selectedKeys.length) {
            message.info('请先选择模板')
            return
        }
        const currentInfo = state.templateList.find(item => item.templateId === state.treeProps.selectedKeys[0])
        if (currentInfo.status === '上线') {
            message.info('请先下线该模板再继续操作')
            return
        }
        getStageList(
            getStatusPrefix(state.treeProps.selectedKeys[0]),
            result => {
                if (!state.templateStageList.length) {
                    state.templateStageList = [
                        {
                            stageName: undefined,
                            serialNumber: undefined,
                            templateStageId: undefined,
                            uid: $guid()
                        }
                    ]
                } else {
                    state.templateStageList = state.templateStageList.map(item => ({
                        ...item,
                        uid: $guid()
                    }))
                }
                state.projectStageVisible = true
            },
            state.taskType
        )
    }

    const handleAddTask = () => {
        if (!state.treeProps.selectedKeys.length) {
            message.info('请先选择模板')
            return
        }
        const currentInfo = state.templateList.find(item => item.templateId === state.treeProps.selectedKeys[0])
        if (currentInfo.status === '上线') {
            message.info('请先下线该模板再继续操作')
            return
        }
        if (state.templateType !== '交付项目') {
            getStageList(
                getStatusPrefix(state.treeProps.selectedKeys[0]),
                result => {
                    state.taskForm = initTaskForm()
                    state.modalTaskTitle = '新建任务'
                    state.taskVisible = true
                    state.radioDisabled = false
                },
                state.taskType
            )
        } else {
            state.taskForm = initTaskForm()
            state.modalTaskTitle = '新建任务'
            state.taskVisible = true
            state.radioDisabled = false
        }
    }
    function jfMbChange() {
        state.taskForm.templateStageId = undefined
        getStageList(getStatusPrefix(state.treeProps.selectedKeys[0]), result => {}, state.taskForm.taskType)
    }
    const handleEditTask = record => {
        const currentInfo = state.templateList.find(item => item.templateId === state.treeProps.selectedKeys[0])
        if (currentInfo.status === '上线') {
            message.info('请先下线该模板再继续操作')
            return
        }
        if (!record.attachmentList) {
            record.attachmentList = []
        }
        const { dependencyTemplateTaskName, dependencyTemplateTaskSerialNumber, ...oldData } = cloneDeep(record)
        state.taskForm = oldData
        if (state.taskForm?.periodClassifyStart.indexOf('+') !== -1) {
            state.taskForm.periodClassifyStart = state.taskForm.periodClassifyStart.slice(2)
        }
        if (state.taskForm?.periodClassifyEnd.indexOf('+') !== -1) {
            state.taskForm.periodClassifyEnd = state.taskForm.periodClassifyEnd.slice(2)
        }
        getStageList(
            getStatusPrefix(state.treeProps.selectedKeys[0]),
            result => {
                getYlTask(getStatusPrefix(state.treeProps.selectedKeys[0]))
                state.modalTaskTitle = '编辑任务'
                state.taskVisible = true
                state.radioDisabled = true
            },
            state.taskType
        )
    }

    const handleDeleteTask = taskId => {
        const currentInfo = state.templateList.find(item => item.templateId === state.treeProps.selectedKeys[0])
        if (currentInfo.status === '上线') {
            message.info('请先下线该模板再继续操作')
            return
        }
        // 删除模板任务：DELETE
        del(`/solution-ppm/api/v2/built-in-system-ppm/project/template/task/${taskId}`).then(res => {
            if (res.status === 'fail') {
                message.error(res.message)
                return
            }
            message.success('删除成功')
            getTaskList(getStatusPrefix(state.treeProps.selectedKeys[0]), () => {
                state.taskVisible = false
            })
        })
    }
    // 删除阶段
    const handleDeleteStage = (index, item) => {
        if (state.templateStageList.length <= 1) {
            return
        }
        checkTaskExist(item.templateStageId, result => {
            if (result) {
                state.projectStageVisible = false
                Modal.confirm({
                    title: '提示',
                    centered: true,
                    content: '该阶段下包含任务，是否确认删除',
                    onOk() {
                        state.modalStageList.splice(index, 1)
                        state.projectStageVisible = true
                    },
                    onCancel() {
                        state.projectStageVisible = true
                    }
                })
                return
            }
            state.templateStageList.splice(index, 1)
        })
    }
    // 模板上线
    function handleOnline(templateId) {
        checkProjectExit(templateId, isExist => {
            if (!isExist) {
                updateTemplateStatus('上线', templateId, () => {})
            } else {
                Modal.confirm({
                    title: '提示',
                    centered: true,
                    content: '模板重新发布后将对已关联的模板项目数据做覆盖处理，请确认',
                    onOk() {
                        state.templateStatusLoadingId = templateId
                        updateTemplateStatus('上线', templateId, res => {
                            state.templateStatusLoadingId = undefined
                            getTemplateList()
                        })
                    }
                })
            }
        })
    }
    // 模板下线
    function handleOffline(templateId) {
        checkProjectExit(templateId, isExist => {
            if (!isExist) {
                updateTemplateStatus('下线', templateId, () => {})
            } else {
                Modal.confirm({
                    title: '提示',
                    centered: true,
                    content: '模板下线后新建项目将不再展示该模板，请确认',
                    onOk() {
                        state.templateStatusLoadingId = templateId
                        updateTemplateStatus('下线', templateId, res => {
                            state.templateStatusLoadingId = undefined
                            getTemplateList()
                        })
                    }
                })
            }
        })
    }
    // 删除模板
    const handleDeleteTemplate = id => {
        if (id.includes('上线')) {
            message.info('请先下线该模板')
            return
        }
        get(`/solution-ppm/api/v2/built-in-system-ppm/project/template/detail/${getStatusPrefix(id)}`).then(
            ({ data }) => {
                if (data.approvalStatus && data.approvalStatus?.includes('审批中')) {
                    message.info('请通过审批再进行此操作')
                } else {
                    checkProjectExit(getStatusPrefix(id), isExist => {
                        if (!isExist) {
                            //   删除
                            console.log('删除模板')
                            del(
                                `/solution-ppm/api/v2/built-in-system-ppm/project/template/delete/${getStatusPrefix(
                                    id
                                )}`
                            ).then(data => {
                                if (data.code === 200) {
                                    message.success('操作成功')
                                    getTemplateList()
                                } else {
                                    message.error(data.message)
                                }
                            })
                        } else {
                            message.info('该模板已关联项目不允许删除')
                        }
                    })
                }
            }
        )
    }

    const formatStringBySemi = string => {
        return string.split(/;|；/)
    }

    onMounted(() => {
        getTemplateList()
    })

    // 获取模板列表
    function getTemplateList() {
        post('/solution-ppm/api/v2/built-in-system-ppm/project/template/list', {
            templateName: state.templateName
        }).then(res => {
            res.data.forEach(item => {
                item.templateId = `${item.templateId}status${item.status}`
            })
            state.templateList = res.data
        })
    }
    // 取id
    function getStatusPrefix(str) {
        str = str.toString()
        const regex = /(\d+)status/i // 匹配status前面的数字
        const match = str.match(regex)
        if (match && match[1]) {
            return parseInt(match[1].trim(), 10) // 返回匹配到的数字并转换为整数
        } else {
            return null // 如果未匹配到，返回null或者其他你认为合适的默认值
        }
    }

    // 查询模板是否被项目中使用
    function checkProjectExit(id, callback) {
        get(`/solution-ppm/api/v2/built-in-system-ppm/project/template/${id}/project_used`).then(({ data }) => {
            callback(data)
        })
    }

    // 查询项目阶段下是否包含任务
    function checkTaskExist(id, callback) {
        if (!id) {
            // 新建
            callback(false)
            return
        }
        get(`/solution-ppm/api/v2/built-in-system-ppm/project/template/stage/{${id}/task_exist`).then(({ data }) => {
            callback(data)
        })
    }

    // 模板状态更新
    function updateTemplateStatus(status, id, callback) {
        put(`/solution-ppm/api/v2/built-in-system-ppm/project/template/${id}/status`, {
            status: status,
            forceFlag: true
        }).then(res => {
            callback(res)
            if (res.status === 'fail') {
                message.error(res.message)
                return
            }
            message.success('已进入模板' + status + '审批')
        })
    }

    // 项目阶段更新
    function updateStageList(id, params, callback) {
        post(`/solution-ppm/api/v2/built-in-system-ppm/project/template/${id}/stage/latest`, {
            dataList: params,
            stageType: state.taskType
        })
            .then(res => {
                if (res.status === 'fail') {
                    message.error(res.message)
                    return
                }
                callback()
            })
            .finally(() => {
                state.milepostLoading = false
            })
    }
    const ylTaskData = ref([])
    // 查询模板下的任务
    function getTaskList(id, callback) {
        state.tableLoading = true
        get(
            `/solution-ppm/api/v2/built-in-system-ppm/project/template/${id}/detail_list?taskType=${
                state.taskType ? state.taskType : ''
            }`
        )
            .then(res => {
                state.templateDetailList = groupData(res.data)
                callback && callback()
            })
            .finally(() => {
                state.tableLoading = false
                state.milepostLoading = false
            })
    }
    function getYlTask(id, callback) {
        get(`/solution-ppm/api/v2/built-in-system-ppm/project/template/${id}/task_tree`).then(data => {
            ylTaskData.value = formatData(data.data)
            if (state.taskForm.templateTaskId) {
                let tree = cloneDeep(formatData(data.data))
                ylTaskData.value = removeTaskById(tree, state.taskForm.templateTaskId)
            }
        })
    }
    function removeTaskById(tasks, taskIdToRemove) {
        return tasks.reduce((result, task) => {
            if (task.taskId !== taskIdToRemove) {
                if (task.children && task.children.length > 0) {
                    task.children = removeTaskById(task.children, taskIdToRemove)
                }
                result.push(task)
            }
            return result
        }, [])
    }
    function generateUniqueId(idCounter) {
        return `node-${idCounter++}`
    }
    function formatData(list) {
        let result = list.map(item => {
            return {
                taskId: generateUniqueId(item.taskId),
                taskName: item.taskName,
                disabled: item.disabled,
                children: item.children
            }
        })
        return result
    }
    function removeParentTaskId(tasks) {
        return tasks.map(task => {
            // 创建一个新的对象，避免直接修改原始数据
            let newTask = {
                taskName: task.taskName,
                disabled: task.disabled,
                children: []
            }
            // 如果有子任务，则递归处理子任务
            if (task.children && task.children.length > 0) {
                newTask.children = removeParentTaskId(task.children)
            }
            return newTask
        })
    }

    function groupData(data) {
        let stageName = ''
        if (!data || !data.length) {
            return []
        }
        return data.map((item, index) => {
            if (stageName !== item.stageName) {
                stageName = item.stageName
                let rowSpan = 0
                for (let i = 0; i < data.length; i++) {
                    if (i >= index) {
                        if (stageName === data[i].stageName) {
                            rowSpan += 1
                        } else {
                            break
                        }
                    }
                }
                item.rowSpan = rowSpan
                item.border = index
            } else {
                item.rowSpan = 0
            }
            item.rowIndex = index
            return item
        })
    }

    // 查询模板下的项目阶段
    function getStageList(id, callback, type) {
        console.log(type)
        get(`/solution-ppm/api/v2/built-in-system-ppm/project/template/${id}/stage/list?stageType=${type}`).then(
            res => {
                state.templateStageList = res.data
                callback && callback()
            }
        )
    }

    // 创建任务

    function handleCreateTask(id, callback) {
        if (!state.treeProps.selectedKeys.length) {
            return
        }
        post(
            `/solution-ppm/api/v2/built-in-system-ppm/project/template/${getStatusPrefix(
                state.treeProps.selectedKeys[0]
            )}/task`,
            state.taskForm
        ).then(res => {
            if (res.code !== 200) {
                message.error(res.message)
                return
            }
            state.taskVisible = false
            getTaskList(getStatusPrefix(state.treeProps.selectedKeys[0]), () => {
                state.taskVisible = false
                message.success('创建成功')
            })
        })
    }

    function $guid(prefix) {
        function s4() {
            const baseNumber = 0x10000
            const radix = 16
            return Math.floor((1 + Math.random()) * baseNumber)
                .toString(radix)
                .substring(1)
        }

        return `${prefix ? `${prefix}-` : ''}${s4()}${s4()}-${s4()}`
    }

    // 修改模板任务
    function handleUpdateTask(id, callback) {
        if (!state.treeProps.selectedKeys.length) {
            return
        }
        put(
            `/solution-ppm/api/v2/built-in-system-ppm/project/template/task/${state.taskForm.templateTaskId}`,
            state.taskForm
        ).then(res => {
            if (res.code !== 200) {
                message.error(res.message)
                return
            }
            message.success('更新成功')
            getTaskList(getStatusPrefix(state.treeProps.selectedKeys[0]), () => {
                state.taskVisible = false
            })
        })
    }

    function downloadFile(info) {
        const { name, url } = info
        let xhr = new XMLHttpRequest()
        xhr.open('GET', url, true)
        xhr.responseType = 'blob'
        xhr.onload = function () {
            if (xhr.status === 200) {
                if (window.navigator.msSaveOrOpenBlob) {
                    navigator.msSaveBlob(xhr.response, name)
                } else {
                    let link = document.createElement('a')
                    let body = document.querySelector('body')
                    link.href = window.URL.createObjectURL(xhr.response)
                    link.download = name
                    // fix Firefox
                    link.style.display = 'none'
                    body.appendChild(link)
                    link.click()
                    body.removeChild(link)
                    window.URL.revokeObjectURL(link.href)
                }
            }
        }
        xhr.send()
    }

    // 角色管理
    const leaderRef = ref(null)
    const responsibleRef = ref(null)
    const memberRef = ref(null)
    function handleChangeRole() {
        get('/solution-ppm/api/v2/built-in-system-ppm/project/template/role/info').then(data => {
            if (data.code === 200) {
                state.memberModel = data.data.coreRoleManagementList
                state.responsibleModel = data.data.headRoleManagementList
                state.leaderModel = data.data.leaderRoleManagementList
                state.roleVisible = true
            } else {
                mseeage.error(data.message)
            }
        })
    }
    function handleSubmitRole() {
        const params = {
            leaderRoleManagementList: state.leaderModel,
            headRoleManagementList: state.responsibleModel,
            coreRoleManagementList: state.memberModel
        }
        Promise.all([leaderRef.value.validate(), responsibleRef.value.validate(), memberRef.value.validate()])
            .then(() => {
                put('/solution-ppm/api/v2/built-in-system-ppm/project/template/role', params).then(data => {
                    if (data.code === 200) {
                        message.success('操作成功')
                        state.roleVisible = false
                    } else {
                        message.error(data.message || '修改角色失败')
                    }
                })
            })
            .catch(() => {
                message.error('请检查录入信息')
            })
    }
    const handleAddLeader = () => {
        state.leaderModel.push({
            roleName: undefined,
            serialNumber: undefined,
            roleType: 'LEADER'
        })
    }
    const deleteLeader = (index, item) => {
        state.leaderModel.splice(index, 1)
    }
    const handleAddResponsible = () => {
        state.responsibleModel.push({
            roleName: undefined,
            serialNumber: undefined,
            roleType: 'HEAD'
        })
    }
    const deleteResponsible = (index, item) => {
        state.responsibleModel.splice(index, 1)
    }
    const handleAddMember = () => {
        state.memberModel.push({
            roleName: undefined,
            serialNumber: undefined,
            roleType: 'CORE'
        })
    }
    const deleteMember = (index, item) => {
        state.memberModel.splice(index, 1)
    }
    const directorRoleList = ref([])

    function getRolePeople() {
        get('/solution-ppm/api/v2/built-in-system-ppm/project/template/role/list').then(data => {
            directorRoleList.value = data.data.map(item => {
                return {
                    label: item.roleName,
                    value: item.roleName
                }
            })
        })
    }
    // 项目核心成员排序校验
    const validateSerial = (rule, value) => {
        return new Promise((resolve, reject) => {
            const reg = new RegExp(/^[1-9]\d*$/)
            if (value !== undefined && value !== null) {
                const exists = checkSerialNumberExists(state.memberModel, value)
                if (exists) {
                    reject('排序重复')
                } else if (!reg.test(value)) {
                    reject('请输入1000以内的正整数数字')
                } else {
                    resolve()
                }
            } else {
                reject('请输入1000以内的正整数数字')
            }
        })
    }

    // 领导小组排序校验
    const validateLeader = (rule, value) => {
        return new Promise((resolve, reject) => {
            const reg = new RegExp(/^[1-9]\d*$/)
            if (value !== undefined && value !== null) {
                const exists = checkSerialNumberExists(state.leaderModel, value)
                if (exists) {
                    reject('排序重复')
                } else if (!reg.test(value)) {
                    reject('请输入1000以内的正整数数字')
                } else {
                    resolve()
                }
            } else {
                reject('请输入1000以内的正整数数字')
            }
        })
    }

    // 项目负责人排序校验
    const validateResponsible = (rule, value) => {
        return new Promise((resolve, reject) => {
            const reg = new RegExp(/^[1-9]\d*$/)
            if (value !== undefined && value !== null) {
                const exists = checkSerialNumberExists(state.responsibleModel, value)
                if (exists) {
                    reject('排序重复')
                } else if (!reg.test(value)) {
                    reject('请输入1000以内的正整数数字')
                } else {
                    resolve()
                }
            } else {
                reject('请输入1000以内的正整数数字')
            }
        })
    }

    function checkSerialNumberExists(array, serialNumberToCheck) {
        let count = 0 // 计数器，用于计算具有相同 serialNumber 的项的数量

        for (let i = 0; i < array.length; i++) {
            if (array[i].serialNumber === serialNumberToCheck) {
                count++ // 每当找到一个具有相同 serialNumber 的项，计数器加一
                if (count > 1) {
                    return true // 如果数量大于1，表示有重复，返回true
                }
            }
        }
        return false // 如果数量不大于1，表示没有重复，返回false
    }

    // 项目核心成员排序校验
    const validateSerialName = (rule, value) => {
        return new Promise((resolve, reject) => {
            if (value !== undefined && value !== null) {
                const exists = checkSerialNameExists(value)
                if (exists) {
                    reject('角色名称重复')
                } else {
                    resolve()
                }
            } else {
                reject('请输入角色名称')
            }
        })
    }

    // 领导小组排序校验
    const validateLeaderName = (rule, value) => {
        return new Promise((resolve, reject) => {
            if (value !== undefined && value !== null) {
                const exists = checkSerialNameExists(value)
                if (exists) {
                    reject('角色名称重复')
                } else {
                    resolve()
                }
            } else {
                reject('请输入角色名称')
            }
        })
    }

    // 项目负责人排序校验
    const validateResponsibleName = (rule, value) => {
        return new Promise((resolve, reject) => {
            if (value !== undefined && value !== null) {
                const exists = checkSerialNameExists(value)
                if (exists) {
                    reject('角色名称重复')
                } else {
                    resolve()
                }
            } else {
                reject('请输入角色名称')
            }
        })
    }

    function checkSerialNameExists(roleName) {
        let array = [...state.leaderModel, ...state.responsibleModel, ...state.memberModel]
        let count = 0 // 计数器，用于计算具有相同 serialNumber 的项的数量
        for (let i = 0; i < array.length; i++) {
            if (array[i].roleName.toString() === roleName) {
                count++ // 每当找到一个具有相同 serialNumber 的项，计数器加一
                if (count > 1) {
                    return true // 如果数量大于1，表示有重复，返回true
                }
            }
        }
        return false // 如果数量不大于1，表示没有重复，返回false
    }

    // 父上传文件
    function handlerUpload(file) {
        const data = new FormData()
        data.append('file', file)

        post('/file-storage/api/v1/file/upload', data)
            .then(({ data: { fullUrl } }) => {
                if (data) {
                    // 新文件对象
                    const newFile = {
                        uid: file.uid,
                        lastModified: file.lastModified,
                        name: file.name,
                        size: file.size,
                        type: file.type,
                        status: 'done',
                        url: fullUrl
                    }

                    // 去重，保留一个副本
                    state.taskForm.attachmentList = [
                        // 保留已存在文件（去除重复）
                        ...state.taskForm.attachmentList.filter(
                            item => item.uid !== file.uid && item.name !== file.name
                        ),
                        // 添加新的文件
                        newFile
                    ]
                }
            })
            .catch(e => {
                message.error('上传失败' + e)
            })

        return false
    }
    // 父移除文件
    function handlerRemove(file) {
        state.taskForm.attachmentList = state.taskForm.attachmentList.filter(item => item.uid !== file.uid)
    }
    // 父上传文件
</script>
<style lang="less" scoped>
    .page_root {
        width: 100%;
        height: 100%;
        overflow: auto;
    }
    .page_root :deep(.@{ant-prefix}-spin-nested-loading),
    .page_root :deep(.@{ant-prefix}-spin-container) {
        height: 100%;
    }
    .page_root :deep(.@{ant-prefix}-spin-container .@{ant-prefix}-table-wrapper) {
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
    }
    .page_root :deep(.@{ant-prefix}-table) {
        flex: auto;
        overflow: auto;
    }
    .table-moreBtn_down {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        width: 100px;
    }

    .table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
        background: #ebf1ff;
    }

    /*  表格树结构样式处理，展开按钮层级增加*/
    :deep(.@{ant-prefix}-table-row-expand-icon) {
        z-index: 1;
    }
    /*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
    :deep(.@{ant-prefix}-table-row-level-1 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 15px !important;
        width: calc(100% - 15px);
    }
    :deep(.@{ant-prefix}-table-row-level-2 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 30px !important;
        width: calc(100% - 30px);
    }
    :deep(.@{ant-prefix}-table-row-level-3 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 45px !important;
        width: calc(100% - 45px);
    }
    :deep(.@{ant-prefix}-table-row-level-4 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 60px !important;
        width: calc(100% - 60px);
    }

    /* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
    :deep(.@{ant-prefix}-transfer-list) {
        height: 100%;
        width: 50%;
    }

    /*样式*/
    .vid_a7g6eyj5wh :deep(.@{ant-prefix}-table-thead) > tr {
        height: 40px;
    }

    .vid_a7g6eyj5wh :deep(.@{ant-prefix}-table-thead) > tr > th {
        background: #3875ff;
        font-size: 14px;
        font-family: arial, helvetica, 'microsoft yahei';
        font-weight: 600;
        color: #ffffff;
        border-bottom: 1px solid #3875ff;
        padding: 8px 16px;
    }

    .vid_a7g6eyj5wh
        :deep(.@{ant-prefix}-table.@{ant-prefix}-table-bordered)
        .@{ant-prefix}-table-container
        .@{ant-prefix}-table-thead
        > tr:not(:last-child)
        > th {
        border-bottom: 1px solid #d9d9d9;
    }

    .vid_a7g6eyj5wh
        :deep(.@{ant-prefix}-table.@{ant-prefix}-table-bordered)
        .@{ant-prefix}-table-container
        .@{ant-prefix}-table-thead
        > tr
        > th {
        border-right: 1px solid #d9d9d9;
    }

    /* 将表格自带的左边框取消，方便设置表头边框颜色和内容边框颜色 */
    .vid_a7g6eyj5wh :deep(.@{ant-prefix}-table.@{ant-prefix}-table-bordered) .@{ant-prefix}-table-container {
        border-left: none;
    }

    .vid_a7g6eyj5wh
        :deep(.@{ant-prefix}-table.@{ant-prefix}-table-bordered)
        .@{ant-prefix}-table-container
        .@{ant-prefix}-table-thead
        > tr
        > th[colstart='0']:first-child {
        border-left: 1px solid #d9d9d9;
    }

    /* 开启粘性表头后，表格结构会发生变化 需另外处理 */
    .vid_a7g6eyj5wh
        :deep(.@{ant-prefix}-table.@{ant-prefix}-table-bordered)
        .@{ant-prefix}-table-container
        .@{ant-prefix}-table-header
        table {
        border-top: 1px solid #d9d9d9;
    }

    .vid_a7g6eyj5wh
        :deep(.@{ant-prefix}-table.@{ant-prefix}-table-bordered)
        .@{ant-prefix}-table-container
        > .@{ant-prefix}-table-content
        > table {
        border-top: 1px solid #d9d9d9;
    }

    .vid_a7g6eyj5wh
        :deep(.@{ant-prefix}-table-thead)
        > tr
        > th:not(:last-child):not(.@{ant-prefix}-table-selection-column):not(
            .@{ant-prefix}-table-row-expand-icon-cell
        ):not([colspan])::before {
        background: #d9d9d9;
        width: 1px;
    }

    .vid_a7g6eyj5wh :deep(.@{ant-prefix}-table-cell-scrollbar) {
        box-shadow: none;
    }

    .vid_a7g6eyj5wh :deep(.@{ant-prefix}-table-tbody) tr {
        height: 40px;
    }

    .vid_a7g6eyj5wh :deep(.@{ant-prefix}-table-tbody) tr > td {
        font-size: 14px;
        font-family: arial, helvetica, 'microsoft yahei';
        font-weight: 400;
        color: #262626;
        border-bottom: 1px solid #ebebeb;
        padding: 0 16px;
        word-break: break-all;

        .cell-wrapper {
            padding: 0 16px;
        }
    }

    .vid_a7g6eyj5wh :deep(.@{ant-prefix}-table-tbody) tr > td .cell-wrapper {
        padding: 0 16px;
    }

    .vid_a7g6eyj5wh :deep(.@{ant-prefix}-table-empty .@{ant-prefix}-table-tbody tr > td) {
        padding: 0;
    }

    .vid_a7g6eyj5wh :deep(.@{ant-prefix}-table-tbody) tr > td .@{ant-prefix}-btn {
        padding: 0 30px 0 0;
    }

    .vid_a7g6eyj5wh :deep(.@{ant-prefix}-table-tbody) tr > td .@{ant-prefix}-btn:last-child {
        padding: 0;
    }

    .vid_a7g6eyj5wh :deep(.table-striped-odd) td {
        background-color: #ffffff;
    }

    .vid_a7g6eyj5wh :deep(.table-striped-even) td {
        background-color: #fafafa;
    }

    .vid_a7g6eyj5wh
        :deep(.@{ant-prefix}-table.@{ant-prefix}-table-bordered)
        .@{ant-prefix}-table-container
        .@{ant-prefix}-table-tbody
        tr
        > td {
        border-right: 1px solid #ebebeb;
    }

    .vid_a7g6eyj5wh
        :deep(.@{ant-prefix}-table.@{ant-prefix}-table-bordered)
        .@{ant-prefix}-table-container
        .@{ant-prefix}-table-tbody
        tr
        > td:first-child {
        border-left: 1px solid #ebebeb;
    }

    .vid_a7g6eyj5wh {
        width: 100%;
        height: 100%;
    }

    .left-article {
        height: 830px;
        display: block;
        background-color: rgba(255, 255, 255, 1);
        border-right-style: solid;
        border-right-width: 16px;
        border-right-color: #f5f6fa;
        padding: 13px 24px;
    }

    .left-article .search {
        margin-top: 8px;
        margin-bottom: 16px;
    }

    .right-article {
        background: #fff;
        height: 830px;
        padding: 21px;
        position: relative;
    }
    .right-article .text {
        padding-left: 8px;
        margin: auto 0;
        font-weight: 600;
        font-size: 16px;
        line-height: 16px;
        border-left-style: solid;
        border-left-width: 4px;
        border-left-color: #3875ff;
    }

    .right-article .table-wrapper {
        height: 725px;
    }

    .stage-wrapper {
        width: 100px;
        max-height: 100%;
        text-align: center;
        border: 1px solid #d9d9d9;
        border-radius: 4px 0 0 4px;
        min-height: 183px;
    }

    .stage-wrapper .header {
        width: 100%;
        font-size: 14px;
        color: #fff;
        background: #3875ff;
        height: 39px;
        line-height: 39px;
    }

    .stage-wrapper .list {
        width: 98px;
        font-size: 15px;
        color: #262626;
        font-weight: bold;
        height: calc(100% - 40px);
        overflow: auto;
    }

    .stage-wrapper .list span {
        cursor: pointer;
        display: block;
        margin: 16px 0;
    }

    .ellipsis {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        word-break: keep-all;
        overflow-wrap: break-word;
    }

    .download-text {
        color: #3875ff;
        cursor: pointer;
    }

    .task-form .title {
        padding-left: 8px;
        font-weight: 600;
        line-height: 16px;
        margin-bottom: 16px;
        border-left-style: solid;
        border-left-width: 4px;
        border-left-color: #3875ff;
        font-size: 16px;
        color: #262626;
    }

    .task-form .tips {
        font-size: 12px;
        color: #8c8c8c;
        letter-spacing: 0;
        margin-top: -15px;
    }

    .table-text {
        min-width: 70px;
        text-overflow: ellipsis;
        white-space: nowrap;
        overflow: hidden;
    }

    .template-delete {
        margin-left: -25px;
        margin-top: 5px;
    }

    .container {
        width: 100%;
        height: 100%;
    }
    .svg-icon {
        display: none;
        position: relative;
        top: 3px;
        outline: none;
    }
    .tree-btns {
        display: flex;
        justify-content: space-around;
    }
    :deep(.ant3-tree-node-content-wrapper:hover) .svg-icon {
        display: inline-block;
    }

    /*角色管理*/
    .role-title {
        font-family: PingFangSC-Semibold;
        font-size: 16px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 600;
        position: absolute;
        top: -4px;
        left: 8px;
    }
    .role-father {
        position: relative;
        height: 17px;
        border-left: 4px solid #3875ff;
        margin-bottom: 16px;
    }
    .addRowBtn {
        margin-bottom: 20px;
    }
    .role-btn-pic {
        position: relative;
        top: 3px;

        display: inline-block;
        height: 16px;
        width: 16px;
        background-image: url('http://10.40.0.33:9001/file-storage/432858388425709568.png');
        background-size: cover;
    }
    .addRowBtn-role {
        margin-bottom: 24px;
    }
    .addRowBtn-role-last {
        margin-bottom: 16px;
    }
    .role-div {
        margin-bottom: 10px;
        max-height: 170px;
        overflow-y: auto;
        overflow-x: hidden;
    }
    .main-role {
        height: 700px;
        overflow-y: auto;
        overflow-x: hidden;
    }
    /*角色管理*/
    .pt-template :deep(.ant3-form-item-label) {
        width: 110px;
    }
    .role-comm-icon {
        width: 16px;
        height: 16px;
        background-image: url('http://10.40.0.33:9001/file-storage/492789996157626368-source.png');
        background-size: cover;
        cursor: pointer;
    }
    .add-icon {
        width: 16px;
        height: 16px;
        background-image: url('http://10.40.0.33:9001/file-storage/492790240417114112-source.png');
        background-size: cover;
        cursor: pointer;
    }
    .right-btn {
        display: flex;
        gap: 8px;
    }
    .right-tj {
        display: flex;
        gap: 24px;
        align-items: center;
    }
</style>
